package com.wanmait.community.aop;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.wanmait.community.entity.OperationLog;
import com.wanmait.community.service.OperationLogService;
import com.wanmait.community.util.IPUtils;
import com.wanmait.community.util.JWTUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;

@Component//受Spring管理
@Aspect//切面类注解
public class OperationLogAspect {
    @Resource
    private OperationLogService operationLogService;
    //切入点表达式 ，切入com.wanmait.community.service包下面的任意的类或者接口的任意的方法，方法拥有任意的参数个数和参数类型，任意的返回类型
    //排除OperationLogService的save开头的方法
    @Pointcut("execution(* com.wanmait.community.service.*.*(..))"+
            "&& !execution(* com.wanmait.community.service.OperationLogService.save*(..))"+
            "&& !execution(* com.wanmait.community.service.AdminService.login*(..))"+
            "&& !execution(* com.wanmait.community.service.UserService.login*(..))"+
            "&& !execution(* com.wanmait.community.service.OperationLogService.find*(..))"
    )
    public void pointcutExpression() {

    }
    //后置通知的一种 返回通知
    //切入的目标方法正常返回后才会执行的方法，如果目标方法没有返回值ret就是null
    @AfterReturning(value = "pointcutExpression()",returning = "returnValue")
    public void afterReturning(JoinPoint joinPoint, Object returnValue) {
        StringBuilder info = new StringBuilder();
        info.append("目标类：").append(joinPoint.getTarget().getClass().getName()).append(";")
                .append("目标方法：").append(joinPoint.getSignature().getName()).append(";")
                .append("参数：").append(Arrays.toString(joinPoint.getArgs())).append(";");
        if (returnValue != null) {
            info.append("返回类型：").append(returnValue.getClass().getName()).append(";")
                    .append("返回值：").append(returnValue);
        }
        OperationLog operationLog = null;
        try {
            operationLog = new OperationLog();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        operationLog.setInfo(info.toString());
        //获得请求对象
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();
        String ip = IPUtils.getClientIpAddr(request);
        operationLog.setIp(ip);
        // 获取名为 "Authorization" 的请求头
//        String authHeader = request.getHeader("Authorization");
        String token = request.getHeader("token");
        String identityStr = request.getHeader("identity");
        Integer id = Integer.parseInt(JWTUtils.getAudience(token));
        Integer identity = null;
        if (StringUtils.isNotBlank(identityStr)) {
            identity = Integer.parseInt(identityStr);
            if (identity == 1){
                operationLog.setAdminId(id);
            }
            else {
                operationLog.setUserId(id);
            }
        }
        operationLogService.save(operationLog);
    }
}
